freeslot(
	'S_PLAY_TAILSSWIPE',
	'SPR_TSWP'
)
states[S_PLAY_TAILSSWIPE] = {
	sprite = SPR_TSWP,
	frame = A,
	tics = -1,
	nextstate = S_PLAY_FALL
}

addHook("PlayerThink", function(player)
	if player.mo and player.mo.valid
		if player.mo.skin == "tails"
        
        local mo = player.mo
        
        //Extended Flight Section
        if player.charability == CA_FLY
            if (player.powers[pw_tailsfly] or mo.state == S_PLAY_FLY_TIRED)
            and (player.cmd.buttons & BT_SPIN)
            and (player.cmd.buttons & BT_JUMP)
                mo.state = S_PLAY_ROLL
                player.panim = PA_ROLL
                player.pflags = $|PF_JUMPED
                S_StartSound(mo, sfx_spin)
            end
            if (player.powers[pw_tailsfly]) and not (player.tailsfly == 1) and not player.powers[pw_super]
            player.powers[pw_tailsfly] = 12*TICRATE
            player.tailsfly = 1
            end
            if (player.powers[pw_tailsfly]) and not (player.tailsfly == 1) and player.powers[pw_super]
            player.powers[pw_tailsfly] = 99999*TICRATE
            player.tailsfly = 1
            end
            if not (player.tailsfly == 0)
            and P_IsObjectOnGround(player.mo)
            player.tailsfly = 0
            end
        end
        
        //Super Tails
        if (player.pflags & PF_JUMPED)
        and not (player.pflags & PF_THOKKED)
        and (player.cmd.buttons & BT_SPIN)
           S_StartSound(mo, sfx_wdjump)
           P_SetObjectMomZ(mo, 30*FRACUNIT, false)
           player.pflags = $|PF_THOKKED
           mo.state = S_PLAY_FALL
        end
               
        
        //Tails Swipe Section
        if player.cantailsswipe == nil
            player.cantailsswipe = true
        end
        if player.tailsswipe == nil
            player.tailsswipe = false
        end
        if player.actiontime == nil
            player.actiontime = 0
        end
        if not player.lockaim
            player.lockaim = false
        end
        
        if P_PlayerInPain(player)
            player.cantailsswipe = true
            player.actiontime = 0
        end
        
        if (P_IsObjectOnGround(mo))
        and not (player.pflags & PF_SPINNING)
            player.cantailsswipe = true
        end
        
        if not (player.cmd.buttons & BT_CUSTOM1) and mo.state == S_PLAY_TAILSSWIPE
            if (P_IsObjectOnGround(mo))
                mo.state = S_PLAY_RUN
            else
                mo.state = S_PLAY_FALL
            end
            player.actiontime = 0
        end
        
        if (player.cmd.buttons & BT_CUSTOM1)
        //and not (player.actiontime >= 22)
        and not (player.mo.state == S_PLAY_PAIN)
        and not player.tailscoldown
        and (player.speed >= 10*FRACUNIT)
            if (player.cantailsswipe == true)
            and not (mo.state == S_PLAY_TAILSSWIPE)
                mo.state = S_PLAY_TAILSSWIPE
                S_StartSound(mo, sfx_mswing)
            end
            player.actiontime = $+1
        end
        
        if (player.speed < 10*FRACUNIT)
        and (mo.state == S_PLAY_TAILSSWIPE)
           player.actiontime = 0
           mo.state = S_PLAY_WALK
        end
        
        if (mo.state == S_PLAY_TAILSSWIPE)
        and (player.pflags & PF_SPINNING)
            player.actiontime = 0
            mo.state = S_PLAY_ROLL
            player.cantailsswipe = false
        end
        
        if player.lockaim then
            player.lockaim = false
            player.drawangle = player.mo.angle
        end
        
        if not player.tailscoldown
            player.tailscoldown = 0
        else
            player.tailscoldown = $ - 1
        end
        
        if (player.actiontime)
            if (mo.eflags & MFE_SPRUNG)
                if (mo.state == S_PLAY_TAILSSWIPE)
                    S_StartSound(mo, sfx_sprong)
                    player.pflags = $&~PF_JUMPED
                    player.actiontime = 0
                    player.cantailsswipe = false
                    mo.state = S_PLAY_SPRING
                    mo.momz = $*40/33
                end
            end
        end
        
        if (mo.state == S_PLAY_TAILSSWIPE and player.cmd.buttons & BT_CUSTOM1)
        and not (player.mo.state == S_PLAY_PAIN)
        and not (player.powers[pw_carry])
        and (player.speed >= 10*FRACUNIT)
        and (player.cantailsswipe == true)
            local hit = P_SPMAngle(mo, MT_DEMONFIRE, player.drawangle)
			if hit and hit.valid
				hit.momx = player.mo.momx
				hit.momy = player.mo.momy
				hit.momz = player.mo.momz
				hit.fuse = 3
				hit.tics = 3
				hit.flags2 = $|MF2_DONTDRAW
				hit.height = player.mo.height
				hit.radius = player.mo.radius/2*3
			end
            if P_IsObjectOnGround(mo)
                player.lockaim = true
            end
            if ((leveltime % 10 == 0))
                S_StartSound(mo, sfx_mswing)
            end
            if not player.playerline
                player.playerline = 0
            end
            if not player.bounceside
                player.bounceside = 0
            end
            if not player.objectcollide
                player.objectcollide = false
            end
            if lines[player.lastlinehit] and lines[player.lastlinehit].valid
                player.playerline = lines[player.lastlinehit]
                player.bounceside = P_PointOnLineSide(player.mo.x, player.mo.y, player.playerline)
            end
            if player.powers[pw_pushing]
                S_StartSound(mo,sfx_s3k9e)
                local dustcount = 6
                while dustcount > 0
                    dustcount = $ - 1
                    local dust = P_SpawnMobjFromMobj(mo, 0, 0, mo.scale * 18, MT_SPINDUST)
                    dust.state = S_MINECARTSPARK
                    dust.momx = (mo.momx * 3) + (P_RandomRange(-20,20) * FRACUNIT)
                    dust.momy = (mo.momy * 3) + (P_RandomRange(-20,20) * FRACUNIT)
                    dust.momz = P_RandomRange(-3,3) * FRACUNIT
                    dust.scale = FRACUNIT * P_RandomRange(50,125) / 100
                    dust.destscale = 0
                    dust.angle = P_RandomRange(0,ANGLE_180)
                    dust.fuse = 10
                end
                if player.objectcollide
					P_InstaThrust(player.mo, player.mo.angle + ANGLE_180, player.normalspeed*2/3)
				else
                    player.actiontime = 0
                    mo.state = S_PLAY_SPRING
                    P_SetObjectMomZ(mo, 9*FRACUNIT, false)
                    player.cantailsswipe = false
                    if player.bounceside == 1
                        P_InstaThrust(player.mo,R_PointToAngle2(player.playerline.v1.x, player.playerline.v1.y, player.playerline.v2.x, player.playerline.v2.y)+ANGLE_90, player.normalspeed*2/3)
                        player.drawangle = R_PointToAngle2(player.playerline.v1.x, player.playerline.v1.y, player.playerline.v2.x, player.playerline.v2.y)+ANGLE_90
                    else
                        P_InstaThrust(player.mo,R_PointToAngle2(player.playerline.v1.x, player.playerline.v1.y, player.playerline.v2.x, player.playerline.v2.y)+ANGLE_270, player.normalspeed*2/3)
                        player.drawangle = R_PointToAngle2(player.playerline.v1.x, player.playerline.v1.y, player.playerline.v2.x, player.playerline.v2.y)+ANGLE_270
                    end
                end
            end
            if not player.powers[pw_pushing]
            and player.objectcollide
                player.objectcollide = false
            end
            //Anim states
            //if player.actiontime < 4
                //Fast Spin anim
                player.drawangle = mo.angle-ANGLE_45*(player.actiontime-4)
                P_SetMobjStateNF(player.followmobj,S_NULL)
                if P_IsObjectOnGround(mo)
                    P_SpawnSkidDust(player, 15*FRACUNIT, sfx_none)
                end
            /*
            elseif player.actiontime < 12
                //Medium Spin anim
                player.drawangle = mo.angle-ANGLE_45*(player.actiontime-4)
                P_SetMobjStateNF(player.followmobj,S_NULL)
                P_SpawnSkidDust(player, 5*FRACUNIT, sfx_none)
            else
                //Teeter anim
                player.drawangle = mo.angle-ANGLE_45/2*(player.actiontime-4)
                mo.state = S_PLAY_EDGE
                mo.frame = 0
                mo.tics = 0
            end
            */
                //Reset to neutral
                if player.actiontime >= 3*TICRATE and (not player.powers[pw_super])
                    player.actiontime = 0
                    player.tailscoldown = 3*TICRATE
                    player.drawangle = mo.angle
                    mo.state = S_PLAY_SPRING
                    mo.frame = 0
                    P_SetObjectMomZ(mo, 5*FRACUNIT, false)
                end
            end
        end
    end
end)

local function CheckAndCrumble(mo, sec)
	for fof in sec.ffloors()
		if not (fof.flags & FF_EXISTS) continue end -- Does it exist?
		if not (fof.flags & FF_BUSTUP) continue end -- Is it bustable?
    
		if mo.z + mo.height < fof.bottomheight continue end -- Are we too low?
		if mo.z-mo.height > fof.topheight continue end -- Are we too high?

		-- Check for whatever else you may want to    

		EV_CrumbleChain(fof) -- Crumble
	end
end

addHook("MobjLineCollide", function(mo, line)
	if mo and mo.valid
	and mo.player and mo.player.valid
	and mo.player.playerstate == PST_LIVE
	and mo.skin == "tails"
	and mo.player.actiontime
    and mo.state == S_PLAY_TAILSSWIPE
		for _, sec in ipairs({line.frontsector, line.backsector})
			CheckAndCrumble(mo, sec)
		end
	end
end)

local function WeRamIntoObject(plmo, mo)
	if not (plmo and plmo.valid) return end
	if plmo.skin != ("tails") return end
    if plmo.type ~= MT_PLAYER return end
    if plmo.z + plmo.height < mo.z
	or mo.z + mo.height < plmo.z return end
    local player = plmo.player --plmo is the player mobj, this gets the player
	player.objectcollide = true
end

addHook("MobjMoveCollide", WeRamIntoObject, MT_PLAYER)

addHook("MobjDamage", function(mo, mobj, src, dmg, dmgtype)
	if mo and mo.valid
		if mobj and mobj.valid and mobj.player and G_GametypeHasSpectators()
			if mobj.state == S_PLAY_TAILSSWIPE
				mobj.player.actiontime = 0
                mobj.state = S_PLAY_SPRING
                P_SetObjectMomZ(mobj, 9*FRACUNIT, false)
                P_InstaThrust(mobj, mobj.angle, -10*FRACUNIT)
                mobj.player.cantailsswipe = false
				P_DamageMobj(mo, mobj, src, 1)
				mo.flags2 = $&~MF2_FRET
				return false
			end
		end
	end
end, MT_PLAYER)

addHook("PlayerCanDamage", function(player, mobj)
	if player.mo and player.mo.valid and player.mo.skin == "tails"
	and (player.actiontime and player.mo.state == S_PLAY_TAILSSWIPE)
		return true
	end
end)

local function TailsCanBreak(spike, plmo)
    if not (plmo and plmo.valid and plmo.skin == "tails" and plmo.player) return end
	local p = plmo.player
	if (p.actiontime and plmo.state == S_PLAY_TAILSSWIPE)
		if not  ((plmo.z > spike.z+spike.height+20*FRACUNIT) or (plmo.z+plmo.height+20*FRACUNIT < spike.z))
			P_KillMobj(spike, plmo, plmo)
			P_StartQuake(2*FRACUNIT, 4) --A Tiny Screenshake
			return false
		end
	end
end

addHook("MobjCollide", TailsCanBreak, MT_SPIKE)
addHook("MobjCollide", TailsCanBreak, MT_EGGSHIELD)
addHook("MobjCollide", TailsCanBreak, MT_WALLSPIKE)